/******************************************************************************
*  COPYRIGHT MorningCore CO.,LTD
******************************************************************************/

/*****************************************************************
* FileName::    <PUSCH_Bit_Replace.c>
* version::     <1.0.0>
* Purpose:      <deal with QPSK 16QAM and 64QAM>
* Authors:      <shanshan, 2022-11-23>
* Notes:        <no>
******************************************************************/

/******************************************************************************
*  HISTORY OF CHANGES
*   <Date>          <Author>        <Version>       <DESCRIPTION>
*   2022-11-23      shanshan        V1.0.0            Bit replace
******************************************************************************/

/******************************************************************************
*  INCLUDE FILES

******************************************************************************/
#include "../head/ue_tx_pusch_bitreplacing_f.h"

/*----------- function definition-----------------------------------*/
/*****************************************************************************
* Function: PUSCH_Bit_Replace()
* Purpose:  This function performs pusch's modulation
*
* Relation:
Calls       : ....
Called by   : ....
* Params:
*   <Name>          <Type>      <In/Out>    <Description>
 P_DataIp[]         int8          In/Out    input binary bit after scrambling
 ReplaceEn          int8          In        when ACK/CSI-part1/CSI-part2 bit Num <= 2, enable
 ReplaceSymNum      int           In        Replace symbol number
 ReplacePos         int           In        RE position need to be replaced
 ReplaceType        int8
 ModuMod            int8          In        modulation mode

 * Return:  void
* Note:    <no>
*******************************************************************************/
#ifndef  SET_D0
#define  SET_D0  0     // d(k) <== d_(k)
#endif

#ifndef  SET_D1
#define  SET_D1  1     // d(k) <== d_(k-1)
#endif

#ifndef  SET_1
#define  SET_1   2     // d(k) <== 1
#endif

void PUSCH_Bit_Replace
(
    int8    P_DataIp[], // input binary bit after scrambling
    int8    TxFlag, // 1: Tx, 0: Rx
    stULParamTable *SimParam
)
{
	int iSym, iRE = 0, ReplaceMode = 0;		        // loop index
	int base = 0;					// replace pos
	int bit_qm = 0; 
	int i;
	uint32 BitFix1Num = 0; // number of fix 1

	int pat_mx[2][8] = {
		//////// no bundling replace pattern 
		{ SET_D0, SET_D1, SET_1, SET_1, SET_1, SET_1, SET_1, SET_1 }, // ReplaceMode=0, 1-bit
		{ SET_D0, SET_D0, SET_1, SET_1, SET_1, SET_1, SET_1, SET_1}   // ReplaceMode=1, 2-bit		
	};	

	switch (SimParam->ModuMod[SimParam->CW_Idx]) // calc bit_qm according to SimParam->ModuMod[SimParam->CW_Idx]
	{
	case BPSK:
		bit_qm = 1;
		//printf ( "BPSK\n" );
		break;
	case QPSK:
		bit_qm = 2;
		//printf ( "QPSK\n" );
		break;
	case QAM16:
		bit_qm = 4;
		//printf ( "16-QAM\n" );
		break;
	case QAM64:
		bit_qm = 6;
		//printf ( "64-QAM\n" );
		break;
	default:
		bit_qm = 2;
		printf("Error Modulation Config!\n ");
		break;
	}

	////////////////////// bit replacing enable //////////////////////
 	base = 0;
	for (iSym=0; iSym<MAXSYMNUM; iSym++)
	{
		for (iRE=0; iRE<SimParam->PUSCH_RB_Num*SC_PER_RB; iRE++)
		{
			if(SimParam->pusch_re_flag[iSym][iRE] < 4) // -2: CSI2 punctring by ACK, -1: Data punctring by ACK, 0: UL-SCH, 1: ACK, 2:CSI1, 3: CSI2, 4: DMRS, 5: NULL, 6: SRS, 7:PT-RS
			{
				if ((1 == SimParam->pusch_re_flag[iSym][iRE]) // ACK
				|| (-1 == SimParam->pusch_re_flag[iSym][iRE])) // Data punctring by ACK
				{
					if (( SimParam->PUSCH_HARQ_Flag == 1) && ( SimParam->PUSCH_HARQ_A_Len == 1)) // ACK 1bit
					{
						ReplaceMode = 0;
					}
					else if (( SimParam->PUSCH_HARQ_Flag == 1) && ( SimParam->PUSCH_HARQ_A_Len == 2))// ACK 2bit
					{
						ReplaceMode = 1;
					}
					else
					{
						ReplaceMode = 2;
					}
				}
				else	// SCH Data and (ACK bit len > 2)
				{
					ReplaceMode = 2;
				}

				for ( i=0; i<bit_qm; i++ )
				{
					if (ReplaceMode < 2) // SCH Data no BitReplacing
					{
						switch ( pat_mx[ReplaceMode][i])
						{
							case SET_D0 :
			    				break;
							case SET_D1 :
			    				P_DataIp[base+i] = P_DataIp[base+i-1];
			    				break;
							case SET_1  :
								if (1 == TxFlag) // Tx
								{
			    					P_DataIp[base+i] = 1; // x is set to 1
								}
								else // Rx
								{
									P_DataIp[base+i] = 0;	// x is not descrambling										
								}
								BitFix1Num = BitFix1Num + 1;
			    				break;
							default:
			    				break;
						}
					}
				} // end of for ( i=0; i<bit_qm; i++ )
				base = base + bit_qm;
			} // end of if(SimParam->pusch_re_flag[iSym][iRE] < 4)
		} // end of for (iRE=0; iRE<MAXRBNUM*SC_PER_RB; iRE++)
	} // end of for (iSym=0; iSym<MAXSYMNUM; iSym++)
	SimParam->BitFix1Num = BitFix1Num;
}
